{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fTFj8ft5dlbS"
      },
      "source": [
        "##### Copyright 2018 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "lzyBOpYMdp3F"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "m_x4KfSJ7Vt7"
      },
      "outputs": [],
      "source": [
        "#@title MIT License\n",
        "#\n",
        "# Copyright (c) 2017 François Chollet\n",
        "#\n",
        "# Permission is hereby granted, free of charge, to any person obtaining a\n",
        "# copy of this software and associated documentation files (the \"Software\"),\n",
        "# to deal in the Software without restriction, including without limitation\n",
        "# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n",
        "# and/or sell copies of the Software, and to permit persons to whom the\n",
        "# Software is furnished to do so, subject to the following conditions:\n",
        "#\n",
        "# The above copyright notice and this permission notice shall be included in\n",
        "# all copies or substantial portions of the Software.\n",
        "#\n",
        "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n",
        "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n",
        "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n",
        "# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n",
        "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
        "# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n",
        "# DEALINGS IN THE SOFTWARE."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "C9HmC2T4ld5B"
      },
      "source": [
        "# Overfit dan underfit"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kRTxFhXAlnl1"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/keras/overfit_and_underfit\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />Lihat di TensorFlow.org</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/id/tutorials/keras/overfit_and_underfit.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Jalankan di Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/tensorflow/docs-l10n/blob/master/site/id/tutorials/keras/overfit_and_underfit.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />Lihat sumber kode di GitHub</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a href=\"https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/id/tutorials/keras/overfit_and_underfit.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />Unduh notebook</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "19rPukKZsPG6"
      },
      "source": [
        "Seperti biasa, kode dalam contoh ini akan menggunakan API dari `tf.keras`, dimana Anda dapat mempelajari lebih jauh tentang hal ini di Tensorflow [Petunjuk Keras](https://www.tensorflow.org/guide/keras).\n",
        "\n",
        "Pada kedua contoh sebelumnya—teks klasifikasi](https://www.tensorflow.org/tutorials/keras/text_classification_with_hub) dan [prediksi efisiensi bahan bakar](https://www.tensorflow.org/tutorials/keras/regression) — kita melihat bahwa akurasi dari model ketika diuji dengan data validasi akan mencapai puncaknya setelah beberapa kali epoch proses training dilakukan, kemudian nilainya akan stagnan atau mulai menurun.\n",
        "\n",
        "Dengan kata lain, model kita *overfit* terhadap data training. Mempelajari bagaimana untuk menyelesaikan permasalahan *overfitting* sangat penting. Meskipun model kita seringkali memperoleh akurasi yang tinggi pada *set training*, apa yang sebenarnya kita mau adalah membangun model yang dapat bekerja dengan baik pada *set tes* (atau data yang model tersebut belum pernah lihat sebelumnya).\n",
        "\n",
        "Kebalikan dari *overfitting* adalah *underfitting*. Underfitting terjadi ketika masih ada ruang untuk pengembangan model terhadap data tes. Hal ini dapat terjadi karena beberapa hal: Apabila model yang dihasilkan tidak cukup baik, *over-regularized*, atau model belum dilatih cukup lama. Artinya, model neural network belum mempelajari pola yang ada di data training.\n",
        "\n",
        "Jika Anda melatih model terlalu lama, model tersebut akan mulai menjadi overfit dan akan mempelajari pola yang terdapat pada data training yang tidak terdapat pada data tes. Kita membutuhkan keseimbangan. Memahami bagaimana cara untuk melatih model dengan jumlah epoch yang tepat sebagaimana yang akan kita pelajari di sini merupakan skill yang bermanfaat.\n",
        "\n",
        "Untuk menghindari *overfitting*, solusi terbaik adalah dengan menggunakan data training lebih menyeluruh. Dataset seharusnya melingkupi seluruh input yang model dapat urus. Penambahan data mungkin akan berguna jika data yang ditambahkan dapat menjelaskan kasus yang baru dan menarik. \n",
        "\n",
        "Model yang dilatih pada data yang lebih lengkap akan secara alami menggeneralisasi lebih baik. Apabila hal tersebut tidak mungkin untuk dilakukan, solusi terbaik lainnya adalah menggunakan teknik seperti regularisasi. Teknik ini memberikan batasan terhadap jumlah dan tipe informasi yang dapat disimpan oleh model. Apabila model neural network hanya dapat menyimpan sedikit pola, proses optimisasi akan menghendaki model untuk fokus pada pola yang paling penting, pola yang memiliki kemungkinan untuk dapat menggeneralisasi dengan baik.\n",
        "\n",
        "Dala notebook ini, kita akan melakukan eksplorasi beberapa teknik regularisasi yang sering digunakan, dan akan menggunakan teknik tersebut untuk meningkatkan performa dari model klasifikasi."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WL8UoOTmGGsL"
      },
      "source": [
        "## Pengaturan"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9FklhSI0Gg9R"
      },
      "source": [
        "Sebelum memulai, import *package* yang diperlukan:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "5pZ8A2liqvgk"
      },
      "outputs": [],
      "source": [
        "from __future__ import absolute_import, division, print_function, unicode_literals\n",
        "\n",
        "try:\n",
        "  # %tensorflow_version only exists in Colab.\n",
        "  %tensorflow_version 2.x\n",
        "except Exception:\n",
        "  pass\n",
        "import tensorflow as tf\n",
        "\n",
        "from tensorflow.keras import layers\n",
        "from tensorflow.keras import regularizers\n",
        "\n",
        "print(tf.__version__)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "QnAtAjqRYVXe"
      },
      "outputs": [],
      "source": [
        "!pip install git+https://github.com/tensorflow/docs\n",
        "\n",
        "import tensorflow_docs as tfdocs\n",
        "import tensorflow_docs.modeling\n",
        "import tensorflow_docs.plots"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "-pnOU-ctX27Q"
      },
      "outputs": [],
      "source": [
        "from  IPython import display\n",
        "from matplotlib import pyplot as plt\n",
        "\n",
        "import numpy as np\n",
        "\n",
        "import pathlib\n",
        "import shutil\n",
        "import tempfile\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "jj6I4dvTtbUe"
      },
      "outputs": [],
      "source": [
        "logdir = pathlib.Path(tempfile.mkdtemp())/\"tensorboard_logs\"\n",
        "shutil.rmtree(logdir, ignore_errors=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1cweoTiruj8O"
      },
      "source": [
        "## Dataset Higgs\n",
        "\n",
        "Tujuan dari tutorial ini tidak untuk mempelajari fisika partikel, jadi jangan terlalu memikirkan detail dari dataset ini. Data ini memilliki 11&#x202F;000&#x202F;000 baris data, masing-masing memiliki 28 fitur, dan memiliki sebuah label dengan kelas biner."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "YPjAvwb-6dFd"
      },
      "outputs": [],
      "source": [
        "gz = tf.keras.utils.get_file('HIGGS.csv.gz', 'https://archive.ics.uci.edu/ml/machine-learning-databases/00280/HIGGS.csv.gz')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "AkiyUdaWIrww"
      },
      "outputs": [],
      "source": [
        "FEATURES = 28"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SFggl9gYKKRJ"
      },
      "source": [
        "Kelas `tf.data.experimental.CsvDataset` dapat digunakan untuk membaca data csv secara langsung dari file gzip tanpa memerlukan proses dekompresi terlebih dahulu."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "QHz4sLVQEVIU"
      },
      "outputs": [],
      "source": [
        "ds = tf.data.experimental.CsvDataset(gz,[float(),]*(FEATURES+1), compression_type=\"GZIP\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HzahEELTKlSV"
      },
      "source": [
        "Kelas yang digunakan untuk membaca csv tersebut mengembalikan sebuah list skalar untuk masing-masing data. Fungsi berikut ini digunakan untuk menggabungkan list skalar tersebut menjadi (feature_vector, label)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "zPD6ICDlF6Wf"
      },
      "outputs": [],
      "source": [
        "def pack_row(*row):\n",
        "  row = list(row)\n",
        "  label = row[0]\n",
        "  features = tf.stack(row[1:],1)\n",
        "  return features, label"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4oa8tLuwLsbO"
      },
      "source": [
        "TensorFlow sangat efisien ketika beroperasi pada batch data yang besar.\n",
        "\n",
        "Oleh karena itu, kita *repacking* setiap data secara individual membuat sebuah `Dataset` baru yang mengambil batch 10000 data, menggunakan fungsi `repack_row` untuk setiap batch, dan kemudian memisahkan batch-batch tersebut menjadi data individual:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "-w-VHTwwGVoZ"
      },
      "outputs": [],
      "source": [
        "packed_ds = ds.batch(10000).map(pack_row).unbatch()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lUbxc5bxNSXV"
      },
      "source": [
        "Lihatlah beberapa data dari `packed_ds` ini.\n",
        "\n",
        "Fitur yang ada belum dinormalisasi secara sempurna, tetapi nilai tersebut sudah cukup untuk tutorial ini."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "TfcXuv33Fvka"
      },
      "outputs": [],
      "source": [
        "for features,label in packed_ds.batch(1000).take(1):\n",
        "  print(features[0])\n",
        "  plt.hist(features.numpy().flatten(), bins = 101)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ICKZRY7gN-QM"
      },
      "source": [
        "Untuk membuat tutorial ini tetap singkat, hanya 1000 sampel pertama yang digunakan untuk validasi, dan 10 000 sampel selanjutnya untuk training:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "hmk49OqZIFZP"
      },
      "outputs": [],
      "source": [
        "N_VALIDATION = int(1e3)\n",
        "N_TRAIN = int(1e4)\n",
        "BUFFER_SIZE = int(1e4)\n",
        "BATCH_SIZE = 500\n",
        "STEPS_PER_EPOCH = N_TRAIN//BATCH_SIZE"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FP3M9DmvON32"
      },
      "source": [
        "*method* `Dataset.skip` dan `Dataset.take` membuat hal ini menjadi mudah.\n",
        "\n",
        "Pada saat yang bersamaan, gunakan *method* `Dataset.cache` untuk memastikan bahwa loader tidak perlu membaca kembali data dari file setiap epoch:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "H8H_ZzpBOOk-"
      },
      "outputs": [],
      "source": [
        "validate_ds = packed_ds.take(N_VALIDATION).cache()\n",
        "train_ds = packed_ds.skip(N_VALIDATION).take(N_TRAIN).cache()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "9zAOqk2_Px7K"
      },
      "outputs": [],
      "source": [
        "train_ds"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6PMliHoVO3OL"
      },
      "source": [
        "Dataset-dataset ini mengembalikan nilai dari individual data. Gunakan *method* `.batch` untuk membuat batch-batch dengan ukuran data untuk training yang tepat. Sebelum membuat batch, ingat juga untuk `.shuffle` dan `.repeat` set training-nya."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Y7I4J355O223"
      },
      "outputs": [],
      "source": [
        "validate_ds = validate_ds.batch(BATCH_SIZE)\n",
        "train_ds = train_ds.shuffle(BUFFER_SIZE).repeat().batch(BATCH_SIZE)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lglk41MwvU5o"
      },
      "source": [
        "## Menunjukkan overfitting\n",
        "\n",
        "Cara paling sederhana untuk mencegah overfitting adalah dengan memulai model yang sederhana: Sebuah model dengan jumlah parameter dapat dipelajari yang sedikit (ditentukan dengan jumlah layer dan jumlah unit tiap layer). Dalam deep learning, jumlah dari parameter dapat dipelajari dalam sebuah model sering disebut juga dengan \"kapasitas\" model.\n",
        "\n",
        "Secara intiusi, sebuah model dengan lebih banyak parameter akan memiliki lebih banyak \"kapasitas memori\" dan dapat dengan mudah mempelajari pemetaan hubungan antara sampel training dan targetnya, sebuah pemetaan tanpa kemampuan generalisasi, tetapi hal ini akan menjadi tidak bermanfaat ketika membuat prediksi terhadap data yang belum pernah dilihat sebelumnya.\n",
        "\n",
        "Selalu ingat hal ini: model deep learning cenderung mampu untuk fit data training dengan baik, tetapi tantangan yang sebenarnya adalah generalisasi, bukan proses fitting tersebut.\n",
        "\n",
        "Di lain pihak, apabila model neural network memiliki kapasitas memori yang terbatas, model tersebut tidak akan mampu untuk mempelajari pemetaan dengan mudah. Untuk meminimalisir nilai kerugian, model harus mempelajari representasi yang memiliki kemampuan prediktif yang kuat. Pada saat yang bersamaan, apabila Anda membuat model Anda terlalu sederhana, model yang dibuat akan sulit untuk fit terhadap data training. Terdapat keseimbangan antara \"terlalu banyak kapasitas\" dan \"kapasitas tidak tercukupi\".\n",
        "\n",
        "Sayangnya, tidak terdapat formula magis untuk menentukan ukuran atau arsitektur yang tepat dari model Anda (dalam hal jumlah layer, atau jumlah yang tepat untuk setiap layer). Anda harus bereksperimen menggunakan berbagai macam arsitektur yang berbeda.  \n",
        "Untuk menemukan ukuran model yang tepat, hal terbaik yang dilakukan adalah dengan memulai model dengan sedikit layer dan parameter, kemudian mulai menambah ukuran dari layer atau menambah layer baru hingga Anda melihat nilai kerugian validasi menurun.\n",
        "\n",
        "Mulai dengan model sederhana menggunakan  `layers.Dense` sebagai baseline, kemudian buat versi yang lebih besar, dan bandingkan performanya."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_ReKHdC2EgVu"
      },
      "source": [
        "### Prosedur training"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pNzkSkkXSP5l"
      },
      "source": [
        "Banyak model dapat dilatih lebih baik apabila Anda mengurangi learning rate sedikit demi sedikit ketika proses training. Menggunakan `optimizers.schedules` untuk mengurangi learning rate dari waktu ke waktu:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "LwQp-ERhAD6F"
      },
      "outputs": [],
      "source": [
        "lr_schedule = tf.keras.optimizers.schedules.InverseTimeDecay(\n",
        "  0.001,\n",
        "  decay_steps=STEPS_PER_EPOCH*1000,\n",
        "  decay_rate=1,\n",
        "  staircase=False)\n",
        "\n",
        "def get_optimizer():\n",
        "  return tf.keras.optimizers.Adam(lr_schedule)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kANLx6OYTQ8B"
      },
      "source": [
        "Kode di atas mengatur sebuah `schedules.InverseTimeDecay` untuk mengurangi learning rate secara hiperbolik menjadi 1/2 dari nilai awal pada 1000 epoch, 1/3 pada 2000 epoch dan seterusnya."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "HIo_yPjEAFgn"
      },
      "outputs": [],
      "source": [
        "step = np.linspace(0,100000)\n",
        "lr = lr_schedule(step)\n",
        "plt.figure(figsize = (8,6))\n",
        "plt.plot(step/STEPS_PER_EPOCH, lr)\n",
        "plt.ylim([0,max(plt.ylim())])\n",
        "plt.xlabel('Epoch')\n",
        "_ = plt.ylabel('Learning Rate')\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ya7x7gr9UjU0"
      },
      "source": [
        "Setiap model pada tutorial ini akan menggunakan konfigurasi proses training yang sama. Sehingga, pengaturannya harus dilakukan agar dapat digunakan kembali, mulai dengan list dari *callback*.\n",
        "\n",
        "Proses training dalam tutorial ini berjalan untuk banyak epoch yang pendek. Untuk mengurangi *logging noise* gunakan `tfdocs.EpochDots` yang merupakan sebuah `.` untuk tiap epoch dan sebuah set metriks lengkap setiap 100 epoch.\n",
        "\n",
        "Selanjutnya, penggunaan `callbacks.EarlyStopping` untuk menghindari waktu training yang panjang dan tidak perlu. Perhatikan bahwa *callback* ini diatur untuk mencatat nilai `val_binary_crossentropy`, bukan `val_loss`. Perbedaan ini akan menjadi penting nanti.\n",
        "\n",
        "Gunakan `callbacks.TensorBoard` untuk membuat log TensorBoard untuk proses training."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "vSv8rfw_T85n"
      },
      "outputs": [],
      "source": [
        "def get_callbacks(name):\n",
        "  return [\n",
        "    tfdocs.modeling.EpochDots(),\n",
        "    tf.keras.callbacks.EarlyStopping(monitor='val_binary_crossentropy', patience=200),\n",
        "    tf.keras.callbacks.TensorBoard(logdir/name),\n",
        "  ]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VhctzKhBWVDD"
      },
      "source": [
        "Setiap model akan menggunaka pengaturan `Model.compile` dan `Model.fit` yang sama:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "xRCGwU3YH5sT"
      },
      "outputs": [],
      "source": [
        "def compile_and_fit(model, name, optimizer=None, max_epochs=10000):\n",
        "  if optimizer is None:\n",
        "    optimizer = get_optimizer()\n",
        "  model.compile(optimizer=optimizer,\n",
        "                loss='binary_crossentropy',\n",
        "                metrics=['accuracy', 'binary_crossentropy'])\n",
        "\n",
        "  model.summary()\n",
        "\n",
        "  history = model.fit(\n",
        "    train_ds,\n",
        "    steps_per_epoch = STEPS_PER_EPOCH,\n",
        "    epochs=max_epochs,\n",
        "    validation_data=validate_ds,\n",
        "    callbacks=get_callbacks(name),\n",
        "    verbose=0)\n",
        "  return history"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mxBeiLUiWHJV"
      },
      "source": [
        "### Tiny Model"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "a6JDv12scLTI"
      },
      "source": [
        "Mulai dengan training sebuah model linear:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "EZh-QFjKHb70"
      },
      "outputs": [],
      "source": [
        "tiny_model = tf.keras.Sequential([\n",
        "    layers.Dense(16, activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dense(1, activation='sigmoid')\n",
        "])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "X72IUdWYipIS"
      },
      "outputs": [],
      "source": [
        "size_histories = {}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "bdOcJtPGHhJ5"
      },
      "outputs": [],
      "source": [
        "size_histories['Tiny'] = compile_and_fit(tiny_model, 'sizes/Tiny')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rS_QGT6icwdI"
      },
      "source": [
        "Sekarang cek bagaimana performa dari model:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "dkEvb2x5XsjE"
      },
      "outputs": [],
      "source": [
        "plotter = tfdocs.plots.HistoryPlotter(metric = 'binary_crossentropy', smoothing_std=10)\n",
        "plotter.plot(size_histories)\n",
        "plt.ylim([0.5, 0.7])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LGxGzh_FWOJ8"
      },
      "source": [
        "### Model Kecil"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YjMb6E72f2pN"
      },
      "source": [
        "Untuk melihat apakah Anda bisa meningkatkan performa dari model yang lebih sederhana, cobalah secara progresif latih model yang lebih besar:\n",
        "\n",
        "Coba gunakan dua buah *hidden layer* dengan 16 unit tiap layernya:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "QKgdXPx9usBa"
      },
      "outputs": [],
      "source": [
        "small_model = tf.keras.Sequential([\n",
        "    # `input_shape` is only required here so that `.summary` works.\n",
        "    layers.Dense(16, activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dense(16, activation='elu'),\n",
        "    layers.Dense(1, activation='sigmoid')\n",
        "])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "LqG3MXF5xSjR"
      },
      "outputs": [],
      "source": [
        "size_histories['Small'] = compile_and_fit(small_model, 'sizes/Small')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "L-DGRBbGxI6G"
      },
      "source": [
        "### Model Medium"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SrfoVQheYSO5"
      },
      "source": [
        "Sekarang coba 3 buah *hidden layer* dengan 64 unit tiap layernya:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "jksi-XtaxDAh"
      },
      "outputs": [],
      "source": [
        "medium_model = tf.keras.Sequential([\n",
        "    layers.Dense(64, activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dense(64, activation='elu'),\n",
        "    layers.Dense(64, activation='elu'),\n",
        "    layers.Dense(1, activation='sigmoid')\n",
        "])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jbngCZliYdma"
      },
      "source": [
        "Dan latih model menggunakan data yang sama:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Ofn1AwDhx-Fe"
      },
      "outputs": [],
      "source": [
        "size_histories['Medium']  = compile_and_fit(medium_model, \"sizes/Medium\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vIPuf23FFaVn"
      },
      "source": [
        "### Model Besar\n",
        "Sebagai latihan, Anda dapat menggunakan model yang lebih besar lagi, dan lihat seberapa cepat model akan menjadi overfitting. Selanjutnya, mari kita tambahkan lebih banyak kapasitas untuk benchmark neural network ini:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ghQwwqwqvQM9"
      },
      "outputs": [],
      "source": [
        "large_model = tf.keras.Sequential([\n",
        "    layers.Dense(512, activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dense(1, activation='sigmoid')\n",
        "])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "D-d-i5DaYmr7"
      },
      "source": [
        "Dan, latih lagi model menggnakan data yang sama:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "U1A99dhqvepf"
      },
      "outputs": [],
      "source": [
        "size_histories['large'] = compile_and_fit(large_model, \"sizes/large\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Fy3CMUZpzH3d"
      },
      "source": [
        "### Plot kerugian dari training dan validasi"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HSlo1F4xHuuM"
      },
      "source": [
        "Garis solid menunjukkan nilai kerugian dari training, dan garis putus-putus memperlihatkan kerugian dari validasi (ingat: nilai kerugian dari validasi yang lebih rendah mengindikasikan model yang lebih baik)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OLhL1AszdLfM"
      },
      "source": [
        "Membangun sebuah model yang lebih besar memberikan kemampuan yang lebih kuat, jika kekuatan model tersebut tidak dibatasi maka model tersebut akan dengan mudah overfit terhadap set training. \n",
        "\n",
        "Dalam contoh ini, umumnya, hanya model `\"Tiny\"` yang mampu menghindari overfiting, dan setiap model yang lebih besar overfit terhadap data dengan cepat. Untuk model `\"besar\"` Anda perlu merubah plotnya ke dalam skala log untuk dapat melihat apa yang sebenarnya terjadi.\n",
        "\n",
        "Hal ini menjadi jelas apabila Anda plot dan membandingkan antara metriks validasi dan metriks training.\n",
        "\n",
        "* Normal apabila terdapat sedikit perbedaan\n",
        "* Apabila kedua metriks bergerak pada arah yang sama, semuanya baik-baik saja.\n",
        "* Apabila metriks validasi mulai stagnan sedangkan metriks training terus meningkat, model yang Anda buat mungkin dekat dengan overfitting.\n",
        "* Apabila metriks validasi bergerak ke arah yang salah, model tersebut jelas overfitting."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "0XmKDtOWzOpk"
      },
      "outputs": [],
      "source": [
        "plotter.plot(size_histories)\n",
        "a = plt.xscale('log')\n",
        "plt.xlim([5, max(plt.xlim())])\n",
        "plt.ylim([0.5, 0.7])\n",
        "plt.xlabel(\"Epochs [Log Scale]\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UekcaQdmZxnW"
      },
      "source": [
        "Catatan: Semua training proses di atas beroperasi menggunakn `callbacks.EarlyStopping` untuk mengakhiri proses training ketika model sudah tidak mengalami peningkatan performa."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DEQNKadHA0M3"
      },
      "source": [
        "### Melihat di TensorBoard\n",
        "\n",
        "Model-model ini seluruhnya menulis log TensorBoard ketika sedang dilakukan proses training. \n",
        "\n",
        "Untuk membuka TensorBoard dalam notebook, salin kode berikut:\n",
        "\n",
        "```\n",
        "%tensorboard --logdir {logdir}/sizes\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fjqx3bywDPjf"
      },
      "source": [
        "Anda dapat melihat [hasil dari operasi sebelumnya](https://tensorboard.dev/experiment/vW7jmmF9TmKmy3rbheMQpw/#scalars&_smoothingWeight=0.97) of this notebook on [TensorBoard.dev](https://tensorboard.dev/).\n",
        "\n",
        "TensorBoard.dev mengatur pengalaman untuk hosting, tracking, dan sharing eksperimen ML dengan semua orang.\n",
        "\n",
        "TensorBoard juga tersedia dalam bentuk `<iframe>` untuk kepraktisan:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "dX5fcgrADwym"
      },
      "outputs": [],
      "source": [
        "display.IFrame(\n",
        "    src=\"https://tensorboard.dev/experiment/vW7jmmF9TmKmy3rbheMQpw/#scalars&_smoothingWeight=0.97\",\n",
        "    width=\"100%\", height=\"800px\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RDQDBKYZBXF_"
      },
      "source": [
        "Apabila Anda mau membagikan hasil TensorBoard Anda dapat mengupload lognya ke [TensorBoard.dev](https://tensorboard.dev/) dengan menyalin kode berikut dalam notebook.\n",
        "\n",
        "Catatan: Langkah ini membutuhkan akun Google.\n",
        "\n",
        "```\n",
        "!tensorboard dev upload --logdir  {logdir}/sizes\n",
        "```\n",
        "\n",
        "Perhatian: Perintah ini tidak berakhir secara automotais. Hal ini didesain untuk terus menerus mengupload hasil dari eksperimen yang berlangsung. Ketika data Anda telah di upload Anda perlu mengakhirinya menggunakan opsi \"interrupt execution\" yang terdapat dalam notebook Anda."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ASdv7nsgEFhx"
      },
      "source": [
        "## Strategi untuk menghindari overfitting"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YN512ksslaxJ"
      },
      "source": [
        "Sebelum kita masuk ke dalam konten dari bagian ini, salin log training yang didapatkan dari model `\"Tiny\"` di atas, kita akan menggunakannya sebagai baseline untuk perbandingan."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "40k1eBtnQzNo"
      },
      "outputs": [],
      "source": [
        "shutil.rmtree(logdir/'regularizers/Tiny', ignore_errors=True)\n",
        "shutil.copytree(logdir/'sizes/Tiny', logdir/'regularizers/Tiny')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "vFWMeFo7jLpN"
      },
      "outputs": [],
      "source": [
        "regularizer_histories = {}\n",
        "regularizer_histories['Tiny'] = size_histories['Tiny']"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4rHoVWcswFLa"
      },
      "source": [
        "### Menambah berat regularisasi"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kRxWepNawbBK"
      },
      "source": [
        "Anda mungkin familiar dengan prinsip Occam Razor: diberikan dua penjelasan terhadap suatu hal, penjelasan yang kemungkinan besar benar adalah penjelasan yang \"paling sederhana\", penjelasan yang menggunakan sedikit asumsi. Hal ini juga berlaku untuk model yang dipelajari oleh model neural network: diberikan beberapa data training dan sebuah arsitektur neural network, terdapat beberapa set dari nilai berat (beberapa model) yang dapat menjelaskan data, dan model yang lebih sederhana memiliki kemungkinan yang lebih kecil untuk overfit dibandingkan dengan model yang lebih kompleks.\n",
        "\n",
        "Sebuah \"model sederhana\" dalam konteks ini adalah model yang dimana nilai distribusi parameternya memiliki entropi yang lebih rendah (atau model dengan lebih sedikit parameter, seperti yang kita lihat pada bagian sebelumnya). Sehingga cara umum untuk mengurangi *overfitting* adalah dengan memberikan batasan pada kompleksitas dari model dengan cara memaksa berat model tersebut hanya mengambil nilai yang kecil, dimana akan membuat distribusi dari nilai berat menjadi lebih \"reguler\". Hal ini disebut dengan \"regularisasi berat\", dan hal ini dapat dilakukan dengan cara menambahkan suatu *cost* pada fungsi kerugian neural network yang berasosiasi dengan berat yang besar. Tersedia dua jenis *cost* ini:\n",
        "\n",
        "* [regularisasi L1](https://developers.google.com/machine-learning/glossary/#L1_regularization), dimana *cost* yang ditambahkan proporsional terhadap nilai absolute dari koefisien berat (sering disebut dengan \"L1 norm\" dari berat).\n",
        "\n",
        "* [regularisasi L2](https://developers.google.com/machine-learning/glossary/#L2_regularization), dimana *cost* yang ditambahkan proporsional terhadap kuadrat dari nilai koefisien berat (sering disebut dengan kuadrat \"L2 norm\" dari berat). Regularisasi L2 disebut juga *weight decay* dalam konteks neural network. Jangan sampai nama yang berbeda membuat Anda bingung: *weight decay* secara matematis sama dengan regularisasi L2.\n",
        "\n",
        "Regularisasi L1 mendorong berat menuju sebuah model sparse nol. Regularisasi L2 akan melakukan pinalti parameter berat tanpa membuatnya menjadi sparse karena pinalti tersebut hanya akan membuat nilai nol untuk berat yang kecil. Satu hal yang menyebabkan L2 lebih sering digunakan.\n",
        "\n",
        "Dalam `tf.keras`, regularisasi berat ditambahkan dengan memberikan objek *weight regularizer* ke layer sebagai *keyword argument*. Mari tambahkan regularisasi berat L2 sekaarang."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "HFGmcwduwVyQ"
      },
      "outputs": [],
      "source": [
        "l2_model = tf.keras.Sequential([\n",
        "    layers.Dense(512, activation='elu',\n",
        "                 kernel_regularizer=regularizers.l2(0.001),\n",
        "                 input_shape=(FEATURES,)),\n",
        "    layers.Dense(512, activation='elu',\n",
        "                 kernel_regularizer=regularizers.l2(0.001)),\n",
        "    layers.Dense(512, activation='elu',\n",
        "                 kernel_regularizer=regularizers.l2(0.001)),\n",
        "    layers.Dense(512, activation='elu',\n",
        "                 kernel_regularizer=regularizers.l2(0.001)),\n",
        "    layers.Dense(1, activation='sigmoid')\n",
        "])\n",
        "\n",
        "regularizer_histories['l2'] = compile_and_fit(l2_model, \"regularizers/l2\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bUUHoXb7w-_C"
      },
      "source": [
        "`l2(0.001)` berarti setiap koefisien matriks berat pada layer akan bertambah sebanyak `0.001 * weight_coefficient_value**2` dari total **kerugian** sebuah neural network.\n",
        "\n",
        "Hal ini mengapa kita memantau nilai `binary_crossentropy` secara langsung. Karena nilai ini tidak memiliki terpengaruh oleh regularisasi komponen.\n",
        "\n",
        "Jadi, model `\"Large\"` yang sama dengan regularisasi penalti `L2` memiliki performa yang lebih baik:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "7wkfLyxBZdh_"
      },
      "outputs": [],
      "source": [
        "# plotter.plot(regularizer_histories)\n",
        "plt.ylim([0.5, 0.7])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Kx1YHMsVxWjP"
      },
      "source": [
        "Seperti yang dapat Anda lihat, model yang telah diregularisasi `\"L2\"` sekarang jauh lebih kompetitif dengan model `\"Tiny\"`. Model `\"L2\"` lebih resisten terhadap overfitting dibandingkan dengan model `\"besar\"` meskipun keduanya memiliki jumlah parameter yang sama."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JheBk6f8jMQ7"
      },
      "source": [
        "#### Info Tambahan\n",
        "\n",
        "Terdapat dua hal penting yang perlu diperhatikan tentang regularisasi ini.\n",
        "\n",
        "**Pertama:** jika Anda menulis pengulangan training Anda sendiri, Anda harus memastikan model akan mengeluarkan nilai kerugian dari regularisasinya."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "apDHQNybjaML"
      },
      "outputs": [],
      "source": [
        "result = l2_model(features)\n",
        "regularization_loss = tf.add_n(l2_model.losses)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MLhG6fMSjE-J"
      },
      "source": [
        "**Kedua:** Implementasi ini bekerja dengan cara menambahkan pinalti berat terhadap nilai kerugian dari model, kemudian melakukan prosedur optimisasi standard setelah itu.\n",
        "\n",
        "Terdapat pendekatan kedua yaitu selain menjalankan optimizer pada *raw loss*, juga menerapkan *weight decay* terhadap optimizer. \"Decopuled Weight Decay\" seperti ini dapat dilihat pada optimizer seperti `optimizers.FTRL` dan `optimizers.AdamW`."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HmnBNOOVxiG8"
      },
      "source": [
        "### Menambahkan dropout\n",
        "\n",
        "Dropout merupakan salah satu cara paling efektif dan cara paling banyak digunakan sebagai teknik regularisasi pada neural network, dikembangkan oleh Hinton dan muridnya di Universitas Toronto.\n",
        "\n",
        "Penjelasan intuitif mengenai dropout adalah karena node dalam neural network tidak dapat bergantung terhadap output dari node yang lainnya, maka setiap node harus mengeluarkan fitur-fitur yang berguna untuk dirinya sendiri.\n",
        "\n",
        "Dropout, yang diterapkan pada sebuah layer, terdiri atas \"dropping out\" acak (misalkan diatur ke nilai nol) jumlah fitur output dari layer ketika proses training. Misalkan sebuah layer secara normal akan mengembalikan vektor [0.2, 0.5, 1.3, 0.8, 1.1] untuk sample input pada proses training; setelah menerapkan dropout, vektor ini akan akan memiliki beberapa nilai kosong yang terdistribusi acak, misal [0, 0.5, 1.3, 0, 1.1].\n",
        "\n",
        "Nilai \"dropout rate\" adalah fraksi  fitur yang akan di nol-kan; nilai ini biasanya diatur antara 0.2 dan 0.5. Saat proses tes, tidak ada unit yang di drop, tetapi nilai output layer akan di *scaled down* dengan faktor yang sama dengan *dropout rate*, sehingga dapat menyeimbangkan karena terdapat lebih banyak unit yang aktif pada waktu training.\n",
        "\n",
        "Dalam `tf.keras` Anda dapat menggunakan dropout dalam sebuah neural network melalui layer Dropout, dimana layer ini akan diguakan sebelum output layer.\n",
        "\n",
        "Mari tambahkan dua layer dropout pada model neural network kita untuk melihat bagaimana teknik ini dapat mengurangi overfittng:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "OFEYvtrHxSWS"
      },
      "outputs": [],
      "source": [
        "dropout_model = tf.keras.Sequential([\n",
        "    layers.Dense(512, activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(1, activation='sigmoid')\n",
        "])\n",
        "\n",
        "regularizer_histories['dropout'] = compile_and_fit(dropout_model, \"regularizers/dropout\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "SPZqwVchx5xp"
      },
      "outputs": [],
      "source": [
        "plotter.plot(regularizer_histories)\n",
        "plt.ylim([0.5, 0.7])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4zlHr4iaI1U6"
      },
      "source": [
        "Sangat jelas dalam plot ini bahwa dua teknik regularisasi ini meningkatkan perilaku dari model `\"besar\"`. Akan tetapi, keduanya belum mampu mengalahkan model `\"Tiny\"`.\n",
        "\n",
        "Selanjutnya, gunakan kedua teknik regularisasi tersebut, dan lihat apakah hal ini membuat performa model lebih baik."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "u7qMg_7Nwy5t"
      },
      "source": [
        "### Combined L2 + dropout"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "7zfs_qQIw1cz"
      },
      "outputs": [],
      "source": [
        "combined_model = tf.keras.Sequential([\n",
        "    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),\n",
        "                 activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),\n",
        "                 activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),\n",
        "                 activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),\n",
        "                 activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(1, activation='sigmoid')\n",
        "])\n",
        "\n",
        "regularizer_histories['combined'] = compile_and_fit(combined_model, \"regularizers/combined\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "qDqBBxfI0Yd8"
      },
      "outputs": [],
      "source": [
        "plotter.plot(regularizer_histories)\n",
        "plt.ylim([0.5, 0.7])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tE0OoNCQNTJv"
      },
      "source": [
        "Model yang `\"Mengkombinasikan\"` dua metode regularisasi ini jelas merupakan model terbaik sejauh ini."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-dw23T03FEO1"
      },
      "source": [
        "### Melihat di TensorBoard\n",
        "\n",
        "Model-model ini juga dicatat di log TensorBoard.\n",
        "\n",
        "Untuk membuka tensorboard dalam sebuah notebook, salin kode berikut ini:\n",
        "\n",
        "```\n",
        "%tensorboard --logdir {logdir}/regularizers\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "KX3Voac-FEO4"
      },
      "source": [
        "Anda dapat melihat [hasil pada operasi sebelumnya](https://tensorboard.dev/experiment/fGInKDo8TXes1z7HQku9mw/#scalars&_smoothingWeight=0.97) of this notebook on [TensorDoard.dev](https://tensorboard.dev/).\n",
        "\n",
        "TensorBoard juga tersedia dalam bentuk `<iframe>` untuk kepraktisan:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "doMtyYoqFEO5"
      },
      "outputs": [],
      "source": [
        "display.IFrame(\n",
        "    src=\"https://tensorboard.dev/experiment/fGInKDo8TXes1z7HQku9mw/#scalars&_smoothingWeight=0.97\",\n",
        "    width = \"100%\",\n",
        "    height=\"800px\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mds5RXGjIcSu"
      },
      "source": [
        "Ini diupload dengan:\n",
        "\n",
        "```\n",
        "!tensorboard dev upload --logdir  {logdir}/regularizers\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uXJxtwBWIhjG"
      },
      "source": [
        "## Kesimpulan"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gjfnkEeQyAFG"
      },
      "source": [
        "To recap: here are the most common ways to prevent overfitting in neural networks:\n",
        "Untuk ringkasan: Ini beberapa cara yang umum untuk mencegah terjadinya overfitting dalam neural network:\n",
        "\n",
        "* Menggunakan lebih banyak data training.\n",
        "* Mengurangi kapasitas dari neural network.\n",
        "* Menambahkan regularisasi berat\n",
        "* Menambahkan dropout.\n",
        "\n",
        "Two important approaches not covered in this guide are:\n",
        "Dua pendekatan penting yang tidak dibahas dalam petunjuk ini:\n",
        "\n",
        "* data-augmentation\n",
        "* batch normalization\n",
        "\n",
        "Ingat bahwa masing-masing metode dapat membantu mengatasi permasalahan ini, tetapi seringkali menggambungkan beberapa metode dapat menjadi lebih efektif."
      ]
    }
  ],
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "collapsed_sections": [],
      "name": "overfit_and_underfit.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
